# -*- coding: utf-8 -*-
"""
Module Description: 用户输入文本校验逻辑

特殊语言版本需要考虑的部分:
- 英文: 需要支持行内空格
- 韩文: 需要支持行内空格
- 未来还需考虑: 泰语,越南语

待优化:英文下的长度配置不需要令加配置项,单独区分英文/非英文下的数字字母长度(英文为1,非英文为2)

update: 1.将各语言版本Unicode码放入枚举，方便维护和更新
        2.长度上限配置由int改为json，支持新增语言版本，配置中未找到的语言版本默认使用中文对应的长度上限

update: 1.所有语言版本使用统一长度计算方式, 最大长度配置使用字典模式

Date: 2017/01/05
Author:Bai Jin Ping
"""
import re
import unicodedata
import wcwidth

from pyshare.const.lang.tips_info import TipsInfo
from pyshare.const.lang_enum import LangEnum, NeedAllowSpaceLang, \
    LegalUnicode, AllowUnicode
from pyshare.dal.gameconfig.query import getProfileList
from pyshare.framework.firefly_dc.singleton import Singleton
from common.service_config import config, get_remote_service_switch
from pyshare.dal.gameconfig.game_env import get_config_env_set
from framework.firefly_dc.context import action_context_storage
from pyshare.remote_services.sensitive_service import SensitiveService
from pyshare.const.enums.remote_service_switch import ServiceSwitch


class TxtLegalString(object):
    """合法字符"""
    __metaclass__ = Singleton

    def __init__(self):
        self.lang_str = ''
        for l in LegalUnicode:
            for u_l in l:
                self.lang_str += "({0}-{1})".format(*u_l)


class TxtAllowString(object):
    """昵称允许字符"""
    __metaclass__ = Singleton

    def __init__(self):
        self.lang_str = ''
        for l in AllowUnicode:
            for u_l in l:
                self.lang_str += "{0}-{1}".format(*u_l)


class TextHandleStrategy(object):
    """文本处理策略"""
    # 拒绝
    Refuse = 0
    # 替换
    Replace = 1


class TxtBase(object):
    """文本处理基类"""
    __metaclass__ = Singleton

    def __init__(self):
        """初始化屏蔽词库"""
        # 敏感词库
        words = getProfileList('KeyWord')
        self.words = [word.Word for word in words]

        # 敏感词库+内部词库
        words_inner = [word.Word for word in getProfileList('KeyWordInner')]
        self.words_plus = self.words + words_inner

    @staticmethod
    def get_unicode(string):
        """
        若string不是unicode字符串，则转换为unicode字符串返回
        :param string:
        :return:unicdeo
        """
        if type(string) is not unicode:
            return unicode(string)
        return string

    @staticmethod
    def get_legal_match_paten(include_line=False):
        """
        获取字符检查匹配模板
        :param include_line: bool 是否把换行符加入合法字符集中
        :return:
        """
        # (\u2006)六分之一空格，这个没有加入进合法字符集中，由客户端机制避免该字符
        # (\u4e00-\9fa5 汉字)(\u0030-\u0039 数字)(\u0041-\u005a 大写字母)(\u0061-\u007a 小写字母)
        # (\u3001-\u303C \u3040-\u31FF 日文)(\uAC00-\uD7AF 韩文拼音)(\u1100-\u11FF 韩文字母)(\u3130-\u318F 韩文兼容字母)
        # (\u0E00-\u0E7F  泰文)
        # 空格/汉字/数字/大写字母/小写字母/全半角标点(包含;&+ 全半角相等的取一份)/元字符 注意表达式最前面的有个空格

        line_str = '\n\r' if include_line else ''
        base_paten = ur'''^[( ){lang}(～＋－！@#￥%…&（）—“”：？》《·＝、【】‘’；、。，)("'~=!_:`;/,<>}})(\-\*\+\|\{{\$\^\(\)\?\.\[\]{line_str})]+$'''
        return base_paten.format(lang=TxtLegalString().lang_str, line_str=line_str)

    @classmethod
    def is_legal(cls, string, include_line=False):
        """判断文本内容是否在限制字符范围
        :param string: unicode 字符串
        :param include_line: bool 是否把换行符加入合法字符集中
        :return: boolean
        """
        string = TxtBase.get_unicode(string)
        regex = cls.get_legal_match_paten(include_line=include_line)
        if not re.match(regex, string):
            return False
        return True

    @staticmethod
    def is_net_legal(string):
        """判断文本内容是否含有网址"""
        """由于研发敏感词服务有对网址进行屏蔽，服务端不再做处理"""
        # string = TxtBase.get_unicode(string)
        #
        # # regex = ur'([0-9a-zA-Z～＋－！@#￥%…&（）—“”：？》《·＝、【】‘’；、。，~=!_:`;/,<>}\-\*\+\|\{\$\^\(\)\?\.\[\]]+[0-9a-zA-Z]+)'
        # regex = ur'([0-9a-zA-Z]+\.[0-9a-zA-Z]+)'
        # if re.match(regex, string):
        #     return False
        return True

    @staticmethod
    def calculate_input_length(string):
        """
        计算用户输入的字符串的长度

        :param string:传入的字符串
        :return:
        """
        string = TxtBase.get_unicode(string)
        text_length = sum([1 for c in string if unicodedata.category(c) != 'Mn'])
        return text_length

    @staticmethod
    def allow_text(string):
        """昵称允许字符"""
        regex = u'[{lang}]'
        regex = regex.format(lang=TxtAllowString().lang_str)
        if re.search(regex, unicode(string)):
            return True
        return False

    @staticmethod
    def only_number(string):
        return string.isdigit()

    @staticmethod
    def only_alpha(string):
        return string.isalpha()

    @staticmethod
    def only_alnum(string):
        return string.isalnum()

    @staticmethod
    def get_width_cfg():
        # 获取字宽配置
        try:
            width_cfg = get_config_env_set('CharacterWidthDict').get(str(action_context_storage.ctx.lang), 1)
        except:
            width_cfg = 1
        return width_cfg


class TxtReplace(TxtBase):
    """
    文本替换处理类
    """
    __metaclass__ = Singleton

    def sensitive_replace(self, text):
        """
        敏感词替换

        .. version:: 2.9
           增加敏感词服务
        """
        if config["service_switch"]["localconser"]:

            if get_remote_service_switch(ServiceSwitch.Sensitive):
                # 使用敏感词服务进行敏感词替换
                language_code = str(action_context_storage.ctx.lang)
                service_stat, status = SensitiveService().filter(language_code, text)
                if status:
                    text = status

            else:
                for word in self.words:
                    text = text.replace(word, '*' * len(word))

        return True, text

    def decode_replace(self, chars, sensitive=True, include_line=False):
        """解码替换"""
        try:
            chars = unicode(chars)
        except UnicodeError:
            # chars = chars.decode('utf-8', 'ignore')  # 忽略解码失败的字符
            chars = chars.decode('utf-8', 'replace')  # ？代替解码失败的字符
        finally:
            # unicode字符集判断
            if not self.is_legal(chars, include_line=include_line):
                return False, TipsInfo.InputTextKeys.illegalInput

            # 是否是网站的判断
            if not self.is_net_legal(chars):
                return False, TipsInfo.InputTextKeys.illegalInput

        if sensitive:
            return self.sensitive_replace(chars)
        return True, chars

    def try_replace(self, content, include_line=False):
        """尝试处理失败后替换"""
        try:
            boolean, result = self.decode_replace(content, include_line=include_line)
            return boolean, result
        except Exception:
            return True, '???'


class TxtRefuse(TxtBase):
    """文本拒绝处理类"""
    __metaclass__ = Singleton

    def sensitive_refuse(self, text):
        """
        敏感词拒绝

        .. version:: 2.9
           增加敏感词服务
        """

        if config["service_switch"]["localconser"]:

            if get_remote_service_switch(ServiceSwitch.Sensitive):
                # 使用敏感词服务进行敏感词屏蔽
                language_code = str(action_context_storage.ctx.lang)
                service_stat, status = SensitiveService().r_filter(language_code, text)
                if status:
                    return False, TipsInfo.InputTextKeys.existSensitive

            else:
                for word in self.words_plus:
                    if word and text.find(word) != -1:
                        return False, TipsInfo.InputTextKeys.existKeyWord

        return True, text

    def decode_refuse(self, chars, sensitive=True):
        """解码拒绝"""
        try:
            chars = unicode(chars)
        except UnicodeError:
            chars = chars.decode('utf-8')
        finally:
            # unicode字符集判断
            if not self.is_legal(chars):
                return False, TipsInfo.InputTextKeys.illegalInput

            # 是否是网站的判断
            if not self.is_net_legal(chars):
                return False, TipsInfo.InputTextKeys.illegalInput

        if sensitive:
            return self.sensitive_refuse(chars)
        return True, chars

    def try_refuse(self, content):
        """尝试处理失败后拒绝"""
        try:
            return self.decode_refuse(content)
        except Exception:
            return False, TipsInfo.InputTextKeys.illegalInput


class TxtManage(object):
    """输入文本处理类"""
    __metaclass__ = Singleton

    @staticmethod
    def input_manage(text, max_len, stat, lang='', include_line=False, allow_space=False):
        """用户输入管理
        :param text: string 输入文本
        :param lang: string 语言版本
        :param max_len: int 限制长度
        :param stat: 状态 0拒绝/1替换
        :param include_line: 是否把换行符加入合法字符集
        :param allow_space: 是否允许包含空格
        :return: tuple (true, unicode)/(false, waring)
        """
        # 左右两边的空白字符也加入判断

        # 静态文本处理(排除空格、非法拒绝)
        # 联盟名称、联盟简称、角色昵称
        if stat == TextHandleStrategy.Refuse:
            boolean, result = TxtRefuse().try_refuse(text)

        # 动态文本处理(包含空格、非法替换)
        # 坐标收藏、聊天消息、邮件正文、联盟公告、联盟宣言
        elif stat == TextHandleStrategy.Replace:
            boolean, result = TxtReplace().try_replace(text, include_line=include_line)

        # 传入状态参数错误
        else:
            return False, TipsInfo.InputTextKeys.statParameterError

        # 计算长度 空格检测(汉字长度=2/字符长度=1)
        if boolean is True:
            if stat == TextHandleStrategy.Refuse and lang in NeedAllowSpaceLang:
                result = result.strip()
                if not result:
                    return False, TipsInfo.InputKeys.TextEmpty

            # 空格判断
            elif stat == TextHandleStrategy.Refuse and lang not in NeedAllowSpaceLang and ' ' in result and not allow_space:
                return False, TipsInfo.InputTextKeys.textExistSpace

            # 换行符判断
            elif stat == TextHandleStrategy.Refuse and '\n' in result:
                return False, TipsInfo.InputTextKeys.illegalInput

            text_length = TxtBase.calculate_input_length(result)

            # 字符长度判断
            if text_length > max_len:
                return False, TipsInfo.InputTextKeys.textLengthLimited

            text_width = wcwidth.wcswidth(result)

            width_cfg = max_len * TxtBase.get_width_cfg()
            # 字宽判断
            if text_width > width_cfg:
                # 字宽超过
                return False, TipsInfo.InputTextKeys.textLengthLimited
        return boolean, result

    @staticmethod
    def refuse_text(text, lang=''):
        boolean, result = TxtRefuse().try_refuse(text)
        if boolean is True and lang in NeedAllowSpaceLang:
            result = result.strip()
            if not result:
                return False, TipsInfo.InputKeys.TextEmpty

        # 空格判断
        elif boolean is True and lang not in NeedAllowSpaceLang and ' ' in result:
            return False, TipsInfo.InputTextKeys.textExistSpace

        # 换行符判断
        elif boolean is True and '\n' in result:
            return False, TipsInfo.InputTextKeys.illegalInput

        return boolean, result

    @staticmethod
    def replace_text(text):
        boolean, result = TxtReplace().try_replace(text)
        return boolean, result

    @staticmethod
    def calculate_length(text, max_len):
        # 字符长度判断
        text_length = TxtBase.calculate_input_length(text)
        if text_length > max_len:
            return False, TipsInfo.InputTextKeys.textLengthLimited

        # 字宽判断
        text_width = wcwidth.wcswidth(text)
        width_cfg = max_len * TxtBase.get_width_cfg()
        if text_width > width_cfg:
            # 字宽超过
            return False, TipsInfo.InputTextKeys.textLengthLimited
        return True, text


class BaseRefuseTextProcess(object):
    """
    文字分类处理基类(拒绝敏感词)
    """

    def __init__(self, text, max_len=0):
        """
        :param text: 文本
        :param max_len: 最大长度（可选)
        :param self.MaxLength: 类中的最大长度
        """
        if max_len:
            self.MaxLength = max_len
        self.text = text

    def process(self):
        """
        文字处理的基本过程
        :return: (boolean, result: 是否通过验证， 处理后的文本（若未通过则为错误原因))
        """

        # 检查敏感词
        if config["service_switch"]["localconser"]:
            boolean, result = TxtManage.refuse_text(self.text)
            if not boolean:
                return boolean, result
            self.text = result

        # 处理长度
        boolean, result = TxtManage.calculate_length(self.text, self.MaxLength)

        return boolean, result


class BaseReplaceTextProcess(object):
    """
    文字分类处理基类(替换敏感词)
    """

    def __init__(self, text, max_len=0):
        """
        :param text: 文本
        :param max_len: 最大长度（可选)
        :param self.MaxLength: 类中的最大长度
        """
        if max_len:
            self.MaxLength = max_len
        self.text = text

    def process(self):
        """
        文字处理的基本过程
        :return: (boolean, result: 是否通过验证， 处理后的文本（若未通过则为错误原因))
        """

        # 屏蔽敏感词
        boolean, result = TxtManage.replace_text(self.text)
        if not boolean:
            return boolean, result
        self.text = result
        # 处理长度
        boolean, result = TxtManage.calculate_length(self.text, self.MaxLength)
        return boolean, result


class Text_SimpleManager(object):
    """
    简单文本本地处理
    默认不做敏感词检测（可设置敏感词检测）
    适用于邮件，聊天
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        if max_len:
            self.max_len = max_len

    def text_decode(self, replace_space=True, is_check_sensitive=False):
        if self.stat == TextHandleStrategy.Refuse:
            flag, result = TxtRefuse().decode_refuse(self.text, sensitive=is_check_sensitive)
        else:
            flag, result = TxtReplace().decode_replace(self.text, sensitive=is_check_sensitive)

        if not flag:
            return flag, result

        # 替换前后空格
        if replace_space:
            return True, result.strip()

        return flag, result

    def check_max_len(self, text):
        if self.max_len:
            return TxtManage.calculate_length(text, self.max_len)
        return True, text

    def process(self, replace_space=True, is_check_sensitive=False):
        flag, result = self.text_decode(replace_space=replace_space, is_check_sensitive=is_check_sensitive)
        if not flag:
            return flag, result

        flag, result = self.check_max_len(result)
        if not flag:
            return flag, result
        return True, result


class Text_NickName(BaseRefuseTextProcess):
    """
    玩家昵称处理类
    """

    def __init__(self, text, max_len=0):
        BaseRefuseTextProcess.__init__(self, text, max_len)
        self.lang = str(action_context_storage.ctx.lang)

        # 当非英文时，英文字母和文字的长度一致。
        # 当英文时，英文字母长度根据配置长度，英文长度特殊。
        if max_len > 0:
            self.MaxLength = max_len
        else:
            self.MaxLength = self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('MaxNicknameLengthDict')
        return length_dict.get(self.lang, get_config_env_set('MaxNicknameLength'))

    def process(self):
        # 检查敏感词
        if config["service_switch"]["localconser"]:
            boolean, result = TxtManage.refuse_text(self.text, self.lang)
            if not boolean:
                return boolean, result
            self.text = result

        # 处理长度
        boolean, result = TxtManage.calculate_length(self.text, self.MaxLength)

        return boolean, result


class Text_Message(Text_SimpleManager):
    """
    信息处理类
    默认敏感词替换
    """

    def __init__(self, text, stat=TextHandleStrategy.Replace, max_len=0):
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()
        super(Text_Message, self).__init__(text, stat=stat)

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('MsgMaxLengthDict')
        return length_dict.get(self.lang, get_config_env_set('MsgMaxLength'))


class Text_Mail(Text_SimpleManager):
    """
    邮件处理类
    默认敏感词替换
    """

    def __init__(self, text, stat=TextHandleStrategy.Replace, content=True, max_len=0):
        self.lang = str(action_context_storage.ctx.lang)
        if max_len:
            self.max_len = max_len
        else:
            self.max_len = self.get_max_length_by_lang(content=content)
        super(Text_Mail, self).__init__(text, stat=stat)

    def get_max_length_by_lang(self, content=True):
        """
        获取语言版本最大昵称长度
        :return:
        """
        if content:
            length_dict = get_config_env_set('MsgMailMaxContentDict')
            return length_dict.get(self.lang, get_config_env_set('MsgMailMaxContent'))
        else:
            length_dict = get_config_env_set('MsgMailMaxSubjectDict')
            return length_dict.get(self.lang, get_config_env_set('MsgMailMaxSubject'))


class Text_PrinceName(object):
    """
    皇子起名
    默认为敏感词拒绝
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)

        if max_len > 0:
            self.max_len = max_len
        else:
            self.max_len = self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('PrinceNameLengthDict')
        return length_dict.get(self.lang, get_config_env_set('PrinceNameLength'))

        # return get_config_env_set('PrinceNameLength')

    def process(self):
        """
        文本处理
        泰文支持英文，其他语言版本不支持英文皇子名
        :return:
        """
        if self.lang not in [LangEnum.English, LangEnum.Thailand]:
            if not TxtBase().allow_text(self.text):
                return False, TipsInfo.PrinceKeys.princeNameOnlyChinese
        if config["service_switch"]["localconser"]:
            return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang)
        return True, self.text


class Text_SeekMatePassword(object):
    """
    招亲密码
    默认为敏感词拒绝
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('MarrySeekMatePasswordLengthDict')
        return length_dict.get(self.lang, get_config_env_set('MarrySeekMatePasswordLength'))

    def process(self):
        """
        文本处理
        :return:
        """
        # 跳过空字符串检测
        if self.text and not self.text.isspace():
            return TxtManage.input_manage(self.text, self.max_len, self.stat)
        return True, ""


class Alliance_Name(object):
    """
    联盟名称
    默认为敏感词拒绝
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)

        if max_len > 0:
            self.max_len = max_len
        else:
            self.max_len = self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('AllianceNameLengthDict')
        return length_dict.get(self.lang, get_config_env_set('AllianceNameLength'))

        # return get_config_env_set('AllianceNameLength')

    def process(self):
        """
        文本处理
        :return:
        """
        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang)


class Alliance_Contact(object):
    """
    联盟联系方式
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('AllianceQQGroupLengthDict')
        return length_dict.get(self.lang, get_config_env_set('AllianceQQGroupLength'))

    def process(self):
        """
        文本处理
        :return:
        """
        if self.text.isspace():
            return False, TipsInfo.InputKeys.TextEmpty

        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang)


class Alliance_Wechat(object):
    """
    联盟微信群
    默认只能输入数字和字母
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('AllianceWechatLengthDict')
        return length_dict.get(self.lang, get_config_env_set('AllianceWechatLength'))

    def process(self):
        """
        文本处理
        :return:
        """
        if self.text.isspace():
            return False, TipsInfo.InputKeys.TextEmpty
        if not TxtBase().only_alnum(self.text):
            return False, TipsInfo.InputKeys.OnlyNumber
        else:
            return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang)


class Alliance_InnerMsg(object):
    """
    联盟内部公告
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('AllianceInnerMsgLengthDict')
        return length_dict.get(self.lang, get_config_env_set('AllianceInnerMsgLength'))

    def process(self):
        """
        文本处理
        :return:
        """
        allow_space = False
        if self.lang in NeedAllowSpaceLang:
            allow_space = True
        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang, allow_space=allow_space)


class Alliance_OuterMsg(object):
    """
    联盟外部公告
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('AllianceOuterMsgLengthDict')
        return length_dict.get(self.lang, get_config_env_set('AllianceOuterMsgLength'))

    def process(self):
        """
        文本处理
        :return:
        """
        allow_space = False
        if self.lang in NeedAllowSpaceLang:
            allow_space = True
        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang, allow_space=allow_space)


class Alliance_Password(object):
    """
    联盟密码
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0, least_len=0):
        self.stat = stat
        self.text = text
        self.max_len = max_len if max_len else get_config_env_set("AlliancePasswordLength")
        self.least_len = least_len if least_len else get_config_env_set("AlliancePasswordLengthLeast")

    def process(self):
        """
        文本处理
        :return:
        """
        if self.text.isspace():
            return False, TipsInfo.InputKeys.TextEmpty
        if len(self.text) < self.least_len:
            return False, TipsInfo.InputKeys.textLengthLeast
        if not TxtBase().only_alnum(self.text):
            return False, TipsInfo.InputKeys.OnlyAllNum
        else:
            return TxtManage.input_manage(self.text, self.max_len, self.stat)


class Friend_Visit_Text(object):
    """
    友邦拜访文本
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0, include_line=False):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()
        self.include_line = include_line

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('FriendVisitTextLengthDict')
        return length_dict.get(self.lang, get_config_env_set('FriendVisitTextLength'))

    def process(self):
        """
        文本处理
        :return:
        """

        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang, include_line=self.include_line,
                                      allow_space=True)


class Greeting_Card_Text(object):
    """
    贺卡文本
    """

    def __init__(self, text, stat=TextHandleStrategy.Replace, max_len=0, include_line=False):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()
        self.include_line = include_line

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('GreetingCardTextLengthDict2')
        return length_dict.get(self.lang, get_config_env_set('GreetingCardTextLength'))

    def process(self):
        """
        文本处理
        :return:
        """

        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang, include_line=self.include_line,
                                      allow_space=True)


class Questionnaire_Answer(object):
    """
    调查问卷答案文本
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)

    def text_decode(self, is_check_sensitive=True):
        if self.stat == TextHandleStrategy.Refuse:
            flag, result = TxtRefuse().decode_refuse(self.text, sensitive=is_check_sensitive)
        else:
            flag, result = TxtReplace().decode_replace(self.text, sensitive=is_check_sensitive)

        return flag, result

    def process(self, is_check_sensitive=True):
        flag, result = self.text_decode(is_check_sensitive=is_check_sensitive)

        return flag, result


class SiegelordTagPointText(object):
    """
    攻城掠地标记地点文本
    """

    def __init__(self, text, stat=TextHandleStrategy.Refuse, max_len=0, include_line=False):
        self.stat = stat
        self.text = text
        self.lang = str(action_context_storage.ctx.lang)
        self.max_len = max_len if max_len else self.get_max_length_by_lang()
        self.include_line = include_line

    def get_max_length_by_lang(self):
        """
        获取语言版本最大昵称长度
        :return:
        """
        length_dict = get_config_env_set('CrossSiegelordTagPointTextLengthDict')
        return length_dict.get(self.lang, get_config_env_set('CrossSiegelordTagPointTextLength'))

    def process(self):
        """
        文本处理
        :return:
        """

        return TxtManage.input_manage(self.text, self.max_len, self.stat, self.lang)


if __name__ == '__main__':
    # text = 'aaaabbb'
    # processer = Alliance_Wechat(text=text, max_len=40)
    # print processer.process()
    #
    # print TxtManage.calculate_length(text, 16, True)

    nickname = '哈哈\n'
    test_nickname = Text_NickName(text=nickname)
    print test_nickname.process()
